//
// Created by wuzhuya on 23-3-27.
//

#include "tcp.h"


void tcp_server(int port) {
    pthread_t tcpServerRecv;
    char buff[1024];
    int socketServer = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    if (socketServer < 0) {
        printf("socket error!\n");
        return;
    }
    struct sockaddr_in addr;
    addr.sin_port = htons(port);
    addr.sin_addr.s_addr = inet_addr("0.0.0.0");
    addr.sin_family = AF_INET;
    int bindStatus = bind(socketServer, (struct sockaddr *) &addr, sizeof(addr));
    if (bindStatus < 0) {
        printf("bind error!\n");
        return;
    }
    int listenStatus = listen(socketServer, 5);
    if (listenStatus < 0) {
        printf("listen error!\n");
        return;
    }
//    pthread_create(&tcpServerRecv, NULL, tcp_server_recv_utils, (void *) &socketServer);
    struct sockaddr_in cli_addr;
    memset(&cli_addr, 0, sizeof(struct sockaddr_in));
    socklen_t cliAddrSize = sizeof(cli_addr);
    int socketClient = accept(socketServer, (struct sockaddr *) &cli_addr, &cliAddrSize);
    if (socketClient < 0) {
        printf("accpet error!");
        close(socketServer);
        exit(-1);
    }
    MyTcpSocket myTcpSocket = {socketClient, cli_addr};
    pthread_create(&tcpServerRecv, NULL, tcp_server_recv_message, (void *) &myTcpSocket);
    while (1) {
        char message[1024];
        printf("input message: ");
        scanf("%s", message);
        ssize_t i = send(socketClient, message, 1024, 0);
        if (!i) {
            close(socketClient);
            close(socketServer);
            exit(-1);
        }
    }
}

void *tcp_server_recv_utils(void *socket) {
    int socketServer = (*(int *) socket);
    pthread_t pthread;
    while (1) {
        struct sockaddr_in cli_addr;
        memset(&cli_addr, 0, sizeof(struct sockaddr_in));
        socklen_t cliAddrSize = sizeof(cli_addr);
        int socketClient = accept(socketServer, (struct sockaddr *) &cli_addr, &cliAddrSize);
        if (socketClient < 0) {
            printf("accept error!\n");
            close(socketClient);
            break;
        }
        MyTcpSocket myTcpSocket = {socketClient, cli_addr};
        pthread_create(&pthread, NULL, tcp_server_recv_message, (void *) &myTcpSocket);
    }
    close(socketServer);
    return NULL;
}

void *tcp_server_recv_message(void *mySocket) {
    MyTcpSocket socket = (*(MyTcpSocket *) mySocket);
    int socketClient = socket.socket;
    struct sockaddr_in cli_addr = socket.cli_addr;
    char buf[1024];
    int i = recv(socketClient, buf, 1024, 0);
    while (i > 0) {
        printf("%s:%d -> %s\n", inet_ntoa(cli_addr.sin_addr), ntohs(cli_addr.sin_port), buf);
        i = recv(socketClient, buf, 1024, 0);
    }
    close(socketClient);
    return NULL;
}

void tcp_client(char *host, int port, char *message) {
    char *buf = NULL;
    struct sockaddr_in serv_addr;
    int socketServer = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    if (socketServer < 0) {
        printf("socket error!\n");
        return;
    }
    serv_addr.sin_addr.s_addr = inet_addr(host);
    serv_addr.sin_port = htons(port);
    serv_addr.sin_family = AF_INET;
    int connectStatus = connect(socketServer, (struct sockaddr *) &serv_addr, sizeof(serv_addr));
    if (connectStatus < 0) {
        printf("connect error!\n");
        return;
    }
    ssize_t i = send(socketServer, message, strlen(message), 0);
    if (i < 0) {
        printf("send error!");
    }
//    write(socketServer, message, strlen(message));
//    printf("server message is :%s\n", buf);
    close(socketServer);
}

void tcp_client_no_exec() {
    pthread_t tcpClientRecv;
    char message[1024];
    char host[1024];
    int serverPort;
    memset(host, 0, 1024);
    memset(&serverPort, 0, 4);
    printf("input address: ");
    scanf("%s", host);
    printf("input port: ");
    scanf("%d", &serverPort);
    int sockDes = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP);
    if (sockDes < 0) {
        printf("socket error!\n");
        return;
    }
    struct sockaddr_in addr;
    addr.sin_addr.s_addr = inet_addr(host);
    addr.sin_port = htons(serverPort);
    addr.sin_family = AF_INET;
    int connectStatus = connect(sockDes, (struct sockaddr *) &addr, sizeof(addr));
    if (connectStatus < 0) {
        printf("connection error!");
        return;
    }
    MyTcpSocket myTcpSocket = {sockDes, addr};
    // 开启新线程接收服务端消息
    pthread_create(&tcpClientRecv, NULL, tcp_server_recv_message, (void *) &myTcpSocket);
    while (1) {
        memset(message, 0, 1024);
        printf("input message: ");
        scanf("%s", message);
        ssize_t i = send(sockDes, message, 1024, 0);
        if (i < 0) {
            printf("send error!");
            exit(-1);
        }
    }
}

